﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PSAdmin.Data.Repositories;
using PSAdmin.Core.Security;
using PSAdmin.Data;
using PSAdmin.Core.Domain;
using NHibernate.Criterion;

namespace PSAdmin.Tests
{
    /// <summary>
    /// Summary description for SecurityTests
    /// </summary>
    [TestClass]
    public class SecurityTests : BaseTest
    {
        public SecurityTests()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext) {

            
        }



        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_create_user_role() {
            var repo = new UserRoleRepository(NHibernateHelper.OpenSession());
            var role = new UserRole("Administrators");
            repo.Save(role);
        }

        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_get_existing_role() {
            var repo = new UserRoleRepository(NHibernateHelper.OpenSession());
            var role = repo.GetByName("Administrators");
            Assert.IsNotNull(role);
        }        
        
        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_add_user_to_role() {
            var repo = new UserRoleRepository(NHibernateHelper.OpenSession());
            var role = repo.GetByName("Administrators");

            var user = new UserRoleMapping(@"domain\bfoster");
            role.Users.Add(user);

            repo.Save(role);
        }

        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_get_users_roles()
        {
            var repo = new UserRoleRepository(NHibernateHelper.OpenSession());

            var roles = repo.GetUserRoles(@"domain\bfoster");
            Assert.IsTrue(roles.Count > 0);
        }

        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_add_role_to_script()
        {
            var repo = new UserRoleRepository(NHibernateHelper.OpenSession());
            var scriptRepo = new PSScriptRepository(NHibernateHelper.OpenSession());

            var role = repo.GetByName("Administrators");

            var script = scriptRepo.GetById(688129);

            script.Roles.Add(role);

            scriptRepo.Save(script);
        }

        [TestMethod]
        [DeploymentItem("hibernate.cfg.xml")]
        public void Can_get_scripts_for_users_roles()
        {          
            using (var session = NHibernateHelper.OpenSession())
            {
                var rolesForUser = DetachedCriteria.For<UserRole>()
                        .SetProjection(Projections.Property("Id"))
                        .CreateCriteria("Users")
                            .Add(Expression.Eq("Username", "domain\\bfoster"));

                var scripts = session.CreateCriteria<PSScript>()
                    .CreateCriteria("Roles")
                        .Add(Subqueries.PropertyIn("Id", rolesForUser))
                    .List<PSScript>();
            }
        }
    }
}
